package com.hbk.programe;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

public class Method {
	
	private Modular modular;
	
	private String method;
    private String uri;
    private String result;
    private String name;
    private List<Param> params=new ArrayList<>();
    private String algorithm;
    private List<String> columns=new ArrayList<>();
    private List<String> orders=new ArrayList<>();
    
    private AliasCount count=new AliasCount();
    
	public Modular getModular() {
		return modular;
	}
	public void setModular(Modular modular) {
		this.modular = modular;
	}
	public String getMethod() {
		return method;
	}
	public void setMethod(String method) {
		this.method = method;
	}
	public String getUri() {
		return uri;
	}
	public void setUri(String uri) {
		this.uri = uri;
	}
	public String getResult() {
		return result;
	}
	public void setResult(String result) {
		this.result = result;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public List<Param> getParams() {
		return params;
	}
	public void setParams(List<Param> params) {
		this.params = params;
	}
	public String getAlgorithm() {
		return algorithm;
	}
	public void setAlgorithm(String algorithm) {
		this.algorithm = algorithm;
	}
	public List<String> getColumns() {
		return columns;
	}
	public void setColumns(List<String> columns) {
		this.columns = columns;
	}
    public List<String> getOrders() {
		return orders;
	}
	public void setOrders(List<String> orders) {
		this.orders = orders;
	}
	public String getParamsStr() {
    	StringBuffer str=new StringBuffer();
    	for(Param param: params) {
    		str.append(param.getType()).append(" ").append(param.getVar()).append(", ");
    	}
    	return str.length()==0?" ":str.delete(str.length()-2, str.length()).toString();
    }
	
	public String getSql() {
		StringBuffer attr = new StringBuffer();
		StringBuffer sql = new StringBuffer("select ");
		
		for (String column : columns) {
			String columnAlias = null;
			if (column.indexOf(" ") != -1) {
				String[] arr = column.split(" ");
				column = arr[0];
				columnAlias = arr[1];
			}
			
			String[] arr=column.split("\\.");
			
			if(arr.length==1) {
				attr.append(column).append(columnAlias == null ? "," : " " + columnAlias + ",");
			}else if(arr.length==2){
				Modular pojo=modular.getPojo(arr[0]);
				String alias=count.getAlias(pojo.getClazz(), pojo.getAlias());
				for (Field field : pojo.getFields()) {
					if (field.getName().equals(column.replaceAll(pojo.getClazz() + ".", ""))) {
						if (field.getName().equals(field.getColumn())) {
							if (field.getDataType().equals("DATE")) {
								
								attr.append("DATE_FORMAT(").append(alias).append(".").append(field.getColumn()).append(",").append("'%Y-%m-%d'").append(") ").append(field.getName()).append(columnAlias == null ? "," : " " + columnAlias + ",");
							
							} else if (field.getDataType().equals("DATETIME")) {
								
								attr.append("DATE_FORMAT(").append(alias).append(".").append(field.getColumn()).append(",").append("'%Y-%m-%d %H:%i:%s'").append(") ").append(field.getName()).append(columnAlias == null ? "," : " " + columnAlias + ",");
							
							} else {
								
								attr.append(alias).append(".").append(field.getName()).append(columnAlias == null ? "," : " " + columnAlias + ",");
							
							}
						} else {
							if (field.getDataType().equals("DATE")) {
								
								attr.append("DATE_FORMAT(").append(alias).append(".").append(field.getColumn()).append(",").append("'%Y-%m-%d'").append(") ").append(columnAlias == null ? field.getName() : columnAlias).append(",");
							
							} else if (field.getDataType().equals("DATETIME")) {
								
								attr.append("DATE_FORMAT(").append(alias).append(".").append(field.getColumn()).append(",").append("'%Y-%m-%d %H:%i:%s'").append(") ").append(columnAlias == null ? field.getName() : columnAlias).append(",");
							
							} else if (field.getColumn().endsWith("_id")) {
								
								attr.append(alias).append(".").append(field.getColumn()).append(" ").append(columnAlias == null ? field.getName() + "Id" : columnAlias).append(",");
							
							} else {
								
								attr.append(alias).append(".").append(field.getColumn()).append(" ").append(columnAlias == null ? field.getName() : columnAlias).append(",");
							}
						}
					}
				}
			}else if(arr.length>2) {
				String ref="";
				for(int i=arr.length-2;i>=0;i--) {
					if(ref.length()>0) {
						ref=arr[i]+"."+ref;
					}else {
						ref=arr[i];
					}
				}
				String clazz=arr[0];
				for(int i=1;i<=arr.length-2;i++) {
					clazz=modular.getRefType(StringUtil.capitalize(clazz)+"."+arr[i]);
				}
				
				Modular pojo=modular.getPojo(clazz);
				
				String alias=count.getAlias(ref,pojo.getAlias());
								
				String fieldName=arr[arr.length-1];
				
				for (Field field : pojo.getFields()) {
					if (field.getName().equals(fieldName)) {
						if (field.getName().equals(field.getColumn())) {
							if (field.getDataType().equals("DATE")) {
								
								attr.append("DATE_FORMAT(").append(alias).append(".").append(field.getColumn()).append(",").append("'%Y-%m-%d'").append(") ").append(field.getName()).append(columnAlias == null ? "," : " " + columnAlias + ",");
							
							} else if (field.getDataType().equals("DATETIME")) {
								
								attr.append("DATE_FORMAT(").append(alias).append(".").append(field.getColumn()).append(",").append("'%Y-%m-%d %H:%i:%s'").append(") ").append(field.getName()).append(columnAlias == null ? "," : " " + columnAlias + ",");
							
							} else {
								
								attr.append(alias).append(".").append(field.getName()).append(columnAlias == null ? "," : " " + columnAlias + ",");
							
							}
						} else {
							if (field.getDataType().equals("DATE")) {
								
								attr.append("DATE_FORMAT(").append(alias).append(".").append(field.getColumn()).append(",").append("'%Y-%m-%d'").append(") ").append(columnAlias == null ? field.getName() : columnAlias).append(",");
							
							} else if (field.getDataType().equals("DATETIME")) {
								
								attr.append("DATE_FORMAT(").append(alias).append(".").append(field.getColumn()).append(",").append("'%Y-%m-%d %H:%i:%s'").append(") ").append(columnAlias == null ? field.getName() : columnAlias).append(",");
							
							} else if (field.getColumn().endsWith("_id")) {
								
								attr.append(alias).append(".").append(field.getColumn()).append(" ").append(columnAlias == null ? field.getName() + "Id" : columnAlias).append(",");
							
							} else {
								
								attr.append(alias).append(".").append(field.getColumn()).append(" ").append(columnAlias == null ? field.getName() : columnAlias).append(",");
							}
						}
					}
				}
			}
		}
		
		if (attr.length() == 0) {
			String alias=count.getAlias(modular.getClazz(), modular.getAlias());
			for (Field field : modular.getFields()) {
				if (field.getName().equals(field.getColumn())) {
					if (field.getDataType().equals("DATE")) {
						attr.append("DATE_FORMAT(").append(alias).append(".").append(field.getColumn()).append(",").append("'%Y-%m-%d'").append(") ").append(field.getName()).append(",");
					} else if (field.getDataType().equals("DATETIME")) {
						attr.append("DATE_FORMAT(").append(alias).append(".").append(field.getColumn()).append(",").append("'%Y-%m-%d %H:%i:%s'").append(") ").append(field.getName()).append(",");
					} else {
						attr.append(alias).append(".").append(field.getName()).append(",");
					}
				} else {
					if (field.getDataType().equals("DATE")) {
						attr.append("DATE_FORMAT(").append(alias).append(".").append(field.getColumn()).append(",").append("'%Y-%m-%d'").append(") ").append(field.getName()).append(",");
					} else if (field.getDataType().equals("DATETIME")) {
						attr.append("DATE_FORMAT(").append(alias).append(".").append(field.getColumn()).append(",").append("'%Y-%m-%d %H:%i:%s'").append(") ").append(field.getName()).append(",");
					} else if (field.getColumn().endsWith("_id")) {
						attr.append(alias).append(".").append(field.getColumn()).append(" ").append(field.getName()).append("Id").append(",");
					} else {
						attr.append(alias).append(".").append(field.getColumn()).append(" ").append(field.getName()).append(",");
					}
				}
			}
		}
		
		sql.append(attr.delete(attr.length() - 1, attr.length()));
		
		StringBuffer leftjoin=new StringBuffer();
		Map<String,String> map=count.getMap();
		Object[] os=map.keySet().toArray();
		Arrays.sort(os);
		Modular root=modular.getPojo(os[0].toString());
		leftjoin.append( root.getTable() ).append(" ").append( map.get(os[0].toString()) );
		if(os.length>1) {
			for(int i=1;i<os.length;i++) {
				String refPath=os[i].toString();
				String[] arr=refPath.split("\\.");
				if(arr.length>2) {
					Modular parent=modular.getPojo(StringUtil.capitalize(arr[arr.length-2]));
					Field refField=modular.getRefField(StringUtil.capitalize(arr[arr.length-2])+"."+arr[arr.length-1]);
					Modular child=modular.getPojo(StringUtil.capitalize(arr[arr.length-1]));
					leftjoin.append(" left join ").append(child.getTable()).append(" ").append(map.get(os[i].toString())).append(" on ").append(map.get(os[i].toString())).append(".id=").append(map.get(os[i-1].toString())).append(".").append(refField.getColumn()) ;
				}else {
					String clazz=modular.getRefType(refPath);
					Field refField=modular.getRefField(refPath);
					Modular child=modular.getPojo(clazz);
					leftjoin.append(" left join ").append(child.getTable()).append(" ").append(map.get(os[i].toString())).append(" on ").append(map.get(os[i].toString())).append(".id=").append(map.get(os[0].toString())).append(".").append(refField.getColumn()) ;
				}
			}
		}
		
		sql.append(" from ").append(leftjoin);
		sql.append(" where 1=1");
		return sql.toString();
	}
	
	public List<DtoField> getQueryCondition() {
		List<DtoField> result=new ArrayList<DtoField>();
		for(Param param:params) {
			for (Dto dto : modular.getDtos()) {
				if (dto.getClazz().equals(param.getType())) {
					for (DtoField dtofield : dto.getFields()) {
						String PojoRef=dtofield.getRef().substring(0, dtofield.getRef().lastIndexOf("."));
						String alias=count.getAlias(PojoRef, "");
						Field field=modular.getRefField(dtofield.getRef());
						dtofield.setRefColumn(alias + "." + field.getColumn());
						dtofield.setRefName(field.getName());
						dtofield.setVar(param.getVar());
						result.add(dtofield);
					}
				}
			}
		}
		for(Param param:params) {
			if(param.getRef()!=null) {
				String PojoRef=param.getRef().substring(0, param.getRef().lastIndexOf("."));
				String alias=count.getAlias(PojoRef, "");
				Field field=modular.getRefField(param.getRef());
				
				DtoField dtofield=new DtoField();
				dtofield.setType(param.getType());
				dtofield.setName(param.getVar());
				dtofield.setDto(false);
				dtofield.setRefColumn(alias + "." + field.getColumn());
				dtofield.setRefName(field.getName());
				dtofield.setVar(param.getVar());
				result.add(dtofield);
			}
		}
		return result;
	}
	
	public String getOrder() {
		
		StringBuffer attr = new StringBuffer();
		for (String column : orders) {
			String ref=column.substring(0, column.lastIndexOf("."));
			String alias=count.getAlias(ref, "");
			for (Modular pojo : modular.getPojos()) {
				if (column.startsWith(pojo.getClazz() + ".")) {
					for (Field field : pojo.getFields()) {
						if (field.getName().equals(column.replaceAll(pojo.getClazz() + ".", ""))) {
							attr.append(alias).append(".").append(field.getColumn()).append(",");
						}
					}
				}
			}
		}
		return attr.delete(attr.length() - 1, attr.length()).toString();
	}
    

}
